
#include <assert.h>
#include <gfx/idevice.h>
#include <gfx/iprogram.h>
#include <gfx/iprogramparameter.h>
#include <gfx/ivertexdeclaration.h>
#include <gfx/programparametername.h>
#include <gfx/gl20/mesh/billboardmesh.h>
#include <GL/glew.h>

ceBillboardMeshGL20::ceBillboardMeshGL20()
  : _vertices(0)
  , _indices(0)
  , _vertexDeclaration(0)
  , _stretching(1,1)
{
  CE_OBJECT_CONSTR
}

bool ceBillboardMeshGL20::Initialize(iDevice* device)
{
  ceVertexElement elements[] = {
    ceVertexElement(ceProgramParameterName(PPB_Position0), DT_Float, 3, 0, 20, 0),
    ceVertexElement(ceProgramParameterName(PPB_TexCoord0), DT_Float, 2, 12, 20, 0),
    ceVertexElement()
  };

  float vertices [] = {
    -1, -1, 0,   0, 0,
    -1,  1, 0,   0, 1,
     1,  1, 0,   1, 1,
     1, -1, 0,   1, 0
  };

  unsigned short indices [] = {
    0, 1, 2,
    0, 2, 3
  };

  _vertexDeclaration = device->CreateVertexDeclaration(elements);
  _vertices = device->CreateVertexBuffer(sizeof(vertices), vertices, BDM_Static);
  _indices = device->CreateIndexBuffer(sizeof(indices), indices, BDM_Static);


  _bbox.Clear();
  _bbox.Add(-1, -1, -1);
  _bbox.Add( 1,  1,  1);
  _bbox.Update();

  return _vertexDeclaration && _vertices && _indices;
}

void ceBillboardMeshGL20::SetSize (const ceVector2f& size)
{
  _stretching = size;
}

void ceBillboardMeshGL20::Draw(const ceRenderEnvironment&, iDevice* device)
{
	static ceProgramParameterName semanticStetching ("STRETCHING");
  iProgramParameter* p = device->GetProgram()->GetParameter(semanticStetching);
  if (p)
    {
      p->Bind(_stretching);
    }
  device->SetStreamSource(0, _vertices);
  device->SetIndices(_indices);
  device->SetVertexDeclaration(_vertexDeclaration);
  device->DrawIndexPrimitives(PT_Triangles, DT_UnsignedShort, 6);
}

void ceBillboardMeshGL20::Update(const ceRenderEnvironment& env, iDevice*)
{
}
